//
//  LENetwork.swift
//  UAKA
//
//  Created by 王剑鹏 on 2020/4/26.
//  Copyright © 2020 waing. All rights reserved.
//

import UIKit
import Moya
import ObjectMapper
import Alamofire

struct LENetwork<T: TargetType, M: Mappable> {
    
    // 请求成功的回调
    typealias successCallback = (_ result: M, _ requestMsg:BaseModel) -> Void
    // 请求失败的回调
    typealias failureCallback = (_ error: Error) -> Void
    
    // 发送网络请求
    static func request(
        target: T,
        success: @escaping successCallback,
        failure: failureCallback?
    ) {
//        let provider = MoyaProvider<T>(manager: WebService.manager())   //设置请求头等参数
        let provider = MoyaProvider<T>()  //不设置请求头参数
        debugPrint("provider.manager ====>>> \(provider.manager.session)")
        debugPrint("使用模型 ====>>>>>> \(M.self)")
//        let m = WebService.manager()
//        provider.manager = m
        provider.request(target) { result in
            switch result {
            case let .success(response):
                do {
                    let filteredResponse = try response.filterSuccessfulStatusCodes()
                    if let json = try filteredResponse.mapJSON() as? [String: Any],
                        let baseData = BaseModel.init(JSON: json) {
                        if baseData.status != 1 {
                            throw LENetworkError.statusError(baseData) // 抛出状态错误
                        }
                        if let _data = baseData.data,
                            let redata = M.init(JSON: _data) {
                            success(redata, baseData)
                        }else{
                            throw LENetworkError.modelError(String(describing: M.self)) // 类型解析错误
                        }
                    }
                } catch let error as LENetworkError {
                    print("错误信息 =====>>>>> \(error.message)")
                } catch {
//                    let result = nsdataToJSON(data: response.data as NSData)
                    let result = String(data: response.data, encoding: String.Encoding.utf8)
                    
                    debugPrint("网络失败的结果==== >>>>>> \(result  as AnyObject)")
                    failure?(MoyaError.jsonMapping(response))
                }
            case let .failure(error):
                failure?(error)
            }
        }
    }

    static func request(
        target: T,
        success: @escaping successCallback
    ) {
        LENetwork.request(target: target, success: success, failure: nil)
    }
    
    
}
//MARK: - 超时设置
/**
 在网络请求方法
 static func request(
     target: T,
     success: @escaping successCallback,
     failure: failureCallback?
 ) 中
 使用let provider = MoyaProvider<T>(manager: WebService.manager())
 */
class WebService {
    
    // set false when release
    static var verbose: Bool = true
    
    // session manager
    static func manager() -> Alamofire.SessionManager {
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
        configuration.timeoutIntervalForRequest = 8 // timeout
        let manager = Alamofire.SessionManager(configuration: configuration)
        manager.adapter = CustomRequestAdapter()
        return manager
    }
    
    // request adpater to add default http header parameter
    private class CustomRequestAdapter: RequestAdapter {
        public func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
            var urlRequest = urlRequest
            debugPrint("请求体===>>>> \(urlRequest)")
            urlRequest.setValue("XMLHttpRequest", forHTTPHeaderField: "X-Requested-With")
            return urlRequest
        }
    }
    
//    // response result type
//    enum Result {
//        case success(JSON)
//        case failure(String)
//    }
}


func nsdataToJSON(data: NSData) -> AnyObject? {
    do {
        return try JSONSerialization.jsonObject(with: data as Data, options: .mutableContainers) as AnyObject
    } catch {
        print(error)
    }
    return nil
}
